<template>
  <div class="update-manager">
    <h1>🚀 系统更新管理</h1>
    
    <!-- 系统状态概览 -->
    <div class="status-overview">
      <h2>📊 系统状态</h2>
      <div class="status-cards">
        <div class="status-card">
          <h3>Docker服务</h3>
          <div class="service-list">
            <div v-for="service in systemStatus?.docker_services" :key="service.name" 
                 class="service-item"
                 :class="{ 'running': service.status === 'running' }">
              <span class="service-name">{{ service.name }}</span>
              <span class="service-status">{{ service.status }}</span>
            </div>
          </div>
        </div>
        
        <div class="status-card">
          <h3>镜像状态</h3>
          <div class="image-list">
            <div v-for="image in systemStatus?.images" :key="image.name" class="image-item">
              <span class="image-name">{{ image.name }}</span>
              <span class="image-id">{{ image.id }}</span>
            </div>
          </div>
        </div>
        
        <div class="status-card">
          <h3>存储使用</h3>
          <div class="disk-usage" v-if="systemStatus?.disk_usage">
            <div class="usage-bar">
              <div class="usage-fill" :style="{ width: systemStatus.disk_usage.usage_percent }"></div>
            </div>
            <div class="usage-text">
              {{ systemStatus.disk_usage.used }} / {{ systemStatus.disk_usage.total }} 
              ({{ systemStatus.disk_usage.usage_percent }})
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 更新操作 -->
    <div class="update-operations">
      <h2>🔄 更新操作</h2>
      
      <!-- 检查更新 -->
      <div class="operation-section">
        <button @click="checkUpdates" :disabled="isChecking" class="check-btn">
          {{ isChecking ? '检查中...' : '检查更新' }}
        </button>
        
        <div v-if="updateCheck" class="update-results">
          <p v-if="updateCheck.total_updates > 0" class="has-updates">
            ⚠️ 发现 {{ updateCheck.total_updates }} 个可用更新
          </p>
          <p v-else class="no-updates">✅ 所有组件都是最新版本</p>
        </div>
      </div>
      
      <!-- 组件选择 -->
      <div class="operation-section">
        <h3>选择更新组件</h3>
        <div class="component-selector">
          <label v-for="component in components" :key="component.id">
            <input type="checkbox" v-model="selectedComponents" :value="component.id">
            {{ component.name }}
          </label>
        </div>
      </div>
      
      <!-- 更新选项 -->
      <div class="operation-section">
        <h3>更新选项</h3>
        <div class="update-options">
          <label>
            <input type="checkbox" v-model="updateOptions.backup">
            创建备份
          </label>
          <label>
            <input type="checkbox" v-model="updateOptions.force">
            强制更新
          </label>
          <label>
            <input type="checkbox" v-model="updateOptions.skip_course">
            跳过课程更新
          </label>
        </div>
      </div>
      
      <!-- 执行更新 -->
      <div class="operation-section">
        <button @click="startUpdate" 
                :disabled="isUpdating || selectedComponents.length === 0" 
                class="update-btn">
          {{ isUpdating ? '更新中...' : '开始更新' }}
        </button>
        
        <button @click="rollback" :disabled="isUpdating" class="rollback-btn">
          回滚系统
        </button>
      </div>
    </div>
    
    <!-- 更新进度 -->
    <div v-if="updateProgress && updateProgress.status !== 'idle'" class="update-progress">
      <h2>📈 更新进度</h2>
      <div class="progress-container">
        <div class="progress-bar">
          <div class="progress-fill" :style="{ width: updateProgress.progress + '%' }"></div>
        </div>
        <div class="progress-text">
          {{ updateProgress.message }} ({{ Math.round(updateProgress.progress) }}%)
        </div>
      </div>
      
      <div v-if="updateProgress.status === 'completed'" class="update-success">
        ✅ 更新完成！
      </div>
      
      <div v-if="updateProgress.status === 'failed'" class="update-failed">
        ❌ 更新失败: {{ updateProgress.message }}
      </div>
    </div>
    
    <!-- 更新日志 -->
    <div class="update-logs">
      <h2>📝 更新日志</h2>
      <div class="log-container">
        <div v-for="log in updateLogs" :key="log" class="log-line">
          {{ log }}
        </div>
      </div>
      <button @click="refreshLogs" class="refresh-logs-btn">刷新日志</button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, reactive } from 'vue'
import axios from 'axios'

// 数据定义
const systemStatus = ref(null)
const updateCheck = ref(null)
const updateProgress = ref(null)
const updateLogs = ref([])
const isChecking = ref(false)
const isUpdating = ref(false)

const selectedComponents = ref(['all'])
const updateOptions = reactive({
  backup: true,
  force: false,
  skip_course: false
})

const components = [
  { id: 'all', name: '所有组件' },
  { id: 'docker', name: 'Docker镜像' },
  { id: 'course', name: '课程内容' },
  { id: 'jupyter', name: 'Jupyter服务' },
  { id: 'blockly', name: 'Blockly服务' },
  { id: 'dashboard', name: 'Dashboard服务' }
]

// API函数
const api = {
  getStatus: () => axios.get('/api/update/status'),
  checkUpdates: () => axios.get('/api/update/check-updates'),
  startUpdate: (data) => axios.post('/api/update/update', data),
  getProgress: () => axios.get('/api/update/update-progress'),
  rollback: () => axios.post('/api/update/rollback'),
  getLogs: () => axios.get('/api/update/logs'),
  cleanup: () => axios.delete('/api/update/cleanup')
}

// 功能函数
const loadSystemStatus = async () => {
  try {
    const response = await api.getStatus()
    systemStatus.value = response.data
  } catch (error) {
    console.error('加载系统状态失败:', error)
  }
}

const checkUpdates = async () => {
  isChecking.value = true
  try {
    const response = await api.checkUpdates()
    updateCheck.value = response.data
  } catch (error) {
    console.error('检查更新失败:', error)
  } finally {
    isChecking.value = false
  }
}

const startUpdate = async () => {
  isUpdating.value = true
  try {
    const updateData = {
      components: selectedComponents.value,
      force: updateOptions.force,
      backup: updateOptions.backup,
      skip_course: updateOptions.skip_course
    }
    
    await api.startUpdate(updateData)
    
    // 开始轮询更新进度
    const progressInterval = setInterval(async () => {
      try {
        const response = await api.getProgress()
        updateProgress.value = response.data
        
        if (response.data.status === 'completed' || response.data.status === 'failed') {
          clearInterval(progressInterval)
          isUpdating.value = false
          await loadSystemStatus()
          await refreshLogs()
        }
      } catch (error) {
        console.error('获取更新进度失败:', error)
        clearInterval(progressInterval)
        isUpdating.value = false
      }
    }, 2000)
    
  } catch (error) {
    console.error('开始更新失败:', error)
    isUpdating.value = false
  }
}

const rollback = async () => {
  if (confirm('确定要回滚系统吗？这将恢复到上一个备份状态。')) {
    try {
      await api.rollback()
      alert('系统回滚成功')
      await loadSystemStatus()
    } catch (error) {
      console.error('回滚失败:', error)
      alert('回滚失败: ' + error.message)
    }
  }
}

const refreshLogs = async () => {
  try {
    const response = await api.getLogs()
    updateLogs.value = response.data.logs
  } catch (error) {
    console.error('获取日志失败:', error)
  }
}

// 生命周期
onMounted(() => {
  loadSystemStatus()
  refreshLogs()
})
</script>

<style scoped>
.update-manager {
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

.status-overview {
  margin-bottom: 30px;
}

.status-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  margin-top: 15px;
}

.status-card {
  background: #f8f9fa;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  padding: 15px;
}

.status-card h3 {
  margin: 0 0 10px 0;
  color: #495057;
}

.service-item, .image-item {
  display: flex;
  justify-content: space-between;
  padding: 5px 0;
  border-bottom: 1px solid #e9ecef;
}

.service-item.running .service-status {
  color: #28a745;
}

.usage-bar {
  width: 100%;
  height: 20px;
  background: #e9ecef;
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 5px;
}

.usage-fill {
  height: 100%;
  background: linear-gradient(90deg, #28a745, #ffc107, #dc3545);
  transition: width 0.3s ease;
}

.operation-section {
  margin-bottom: 20px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 8px;
}

.component-selector {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin-top: 10px;
}

.update-options {
  display: flex;
  gap: 20px;
  margin-top: 10px;
}

.check-btn, .update-btn, .rollback-btn {
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  font-size: 16px;
  margin-right: 10px;
}

.check-btn {
  background: #007bff;
  color: white;
}

.update-btn {
  background: #28a745;
  color: white;
}

.rollback-btn {
  background: #dc3545;
  color: white;
}

.check-btn:disabled, .update-btn:disabled, .rollback-btn:disabled {
  background: #6c757d;
  cursor: not-allowed;
}

.update-results {
  margin-top: 10px;
}

.has-updates {
  color: #856404;
  background: #fff3cd;
  padding: 10px;
  border-radius: 5px;
}

.no-updates {
  color: #155724;
  background: #d4edda;
  padding: 10px;
  border-radius: 5px;
}

.progress-container {
  margin: 15px 0;
}

.progress-bar {
  width: 100%;
  height: 30px;
  background: #e9ecef;
  border-radius: 15px;
  overflow: hidden;
  margin-bottom: 10px;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #007bff, #28a745);
  transition: width 0.3s ease;
}

.progress-text {
  text-align: center;
  font-weight: bold;
}

.update-success {
  color: #155724;
  background: #d4edda;
  padding: 15px;
  border-radius: 5px;
  margin-top: 10px;
}

.update-failed {
  color: #721c24;
  background: #f8d7da;
  padding: 15px;
  border-radius: 5px;
  margin-top: 10px;
}

.log-container {
  background: #212529;
  color: #fff;
  padding: 15px;
  border-radius: 5px;
  height: 300px;
  overflow-y: auto;
  font-family: 'Courier New', monospace;
  font-size: 12px;
}

.log-line {
  margin-bottom: 5px;
}

.refresh-logs-btn {
  margin-top: 10px;
  padding: 8px 16px;
  background: #6c757d;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
</style> 